package gui;

import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;

public class LeClasseJavaETransformaEmObjetoClass extends ClassLoader
{
	 /*
	  * Essa funcao cria um objeto CLASS a partir do endereco(url) de onde esta o arquivo .class e do nome da classe e seus pacotes
	  * exemplo de parametros:
	  * caminhoAteClasse = "C:/Users/Mina/Desktop/eclipse-SDK-3.7.1-win32/projetos2/BombWordsFinalPadroesEPrincipiosAntesDeInterfaceSegregation/jogo/DAO.class"
	  	nomeClasseEPacote = "jogo.DAO"
	  	isso ira carregar a classe DAO do pacote jogo que esta no caminho especificado.
	  */
	 @SuppressWarnings("rawtypes")
	public Class loadClass(String caminhoAteClasse, String nomeClasseEPacote) throws ClassNotFoundException, NoClassDefFoundError 
	 {
	        try 
	        {
	        	
	        	FileInputStream input = new FileInputStream(caminhoAteClasse);
	            ByteArrayOutputStream buffer = new ByteArrayOutputStream();
	            int data = input.read();

	            while(data != -1){
	                buffer.write(data);
	                data = input.read();
	            }

	            input.close();

	            byte[] classData = buffer.toByteArray();

	            return defineClass(nomeClasseEPacote,
	                    classData, 0, classData.length);

	        } catch (MalformedURLException e) {
	            e.printStackTrace();
	        } catch (IOException e) {
	            e.printStackTrace(); 
	        }
	        catch(NoClassDefFoundError e)
	        {
	        	throw new NoClassDefFoundError();
	        }

	        return null;
	    }
	 
	 
	 @SuppressWarnings("rawtypes")
	public static void main(String args[])
	 {
		LeClasseJavaETransformaEmObjetoClass leitor = new LeClasseJavaETransformaEmObjetoClass();
		try 
		{
			Class c = leitor.loadClass("C:/Users/Mina/Desktop/eclipse-SDK-3.7.1-win32/projetos2/BombWordsFinalPadroesEPrincipiosAntesDeInterfaceSegregation/jogo/DAO.class", "jogo.DAO");
			System.out.println("classe carregada:" + c.getName());
			System.out.println("");
			
			//se uma classe usa outra classe nos seus metodos, precisaremos loadClass dessa outra classe tb
			
			System.out.println("");
			Class c2 = leitor.loadClass("C:/Users/Mina/Desktop/eclipse-SDK-3.7.1-win32/projetos2/BombWordsFinalPadroesEPrincipiosAntesDeInterfaceSegregation/jogo/PalavrasETraducoes.class", "jogo.PalavrasETraducoes");
			System.out.println("classe carregada:" + c2.getName());
			System.out.println("");
			
			Method[] methods = c.getDeclaredMethods();
			for(int i = 0; i < methods.length; i++)
			{
				System.out.println(methods[i].getName());
			}
			
			System.out.println("");
			Class c3 = leitor.loadClass("C:/Users/Mina/Desktop/eclipse-SDK-3.7.1-win32/projetos2/BombWordsFinalPadroesEPrincipiosAntesDeInterfaceSegregation/jogo/DAOLeituraDeArquivos.class", "jogo.DAOLeituraDeArquivos");
			System.out.println("classe carregada:" + c3.getName());
			System.out.println("");
			
			Method[] methods3 = c3.getDeclaredMethods();
			
			
			for(int i = 0; i < methods.length; i++)
			{
				if(methods3[i].getName().compareTo("somar") == 0)
				{
					try 
					{
						Object objetoDaClasse3 = c3.newInstance();
						//instanciei um novo object a partir de um objeto CLASS
						
						System.out.println("invoquei metodo e o resultado foi " + methods3[i].invoke(objetoDaClasse3, 1, 2));
					} catch (IllegalAccessException e) {
						// TODO Auto-generated catch block
						System.out.println(e);
					} catch (IllegalArgumentException e) {
						// TODO Auto-generated catch block
						System.out.println(e);
					} catch (InvocationTargetException e) {
						// TODO Auto-generated catch block
						System.out.println(e);
					} catch (InstantiationException e) {
						// TODO Auto-generated catch block
						System.out.println(e);
					}
				}
				System.out.println(methods3[i].getName());
			}
		} 
		catch (ClassNotFoundException e) 
		{
			System.out.println(e);
		}
	 }
}
